package com.ultron.app.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.List;

/**
 * 标题：WebClientUtils
 * 说明：
 * 时间：2024/2/29
 * 作者：admin
 */
public class WebClientUtils {
    private WebClient webClient;


    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @ApiModel("请求头")
    public static class Header {

        @ApiModelProperty(value = "key")
        private String key;

        @ApiModelProperty(value = "key")
        private String value;
    }


    /**
     * 默认构建一个WebClient
     * @param baseUrl
     */
    public WebClientUtils(String baseUrl) {
        this.webClient = WebClient.builder()
                .baseUrl(baseUrl)
                .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .build();
    }

    /**
     * 根据header构建一个WebClient
     * @param baseUrl
     * @param headers
     */
    public WebClientUtils(String baseUrl,Header... headers) {
        this.webClient = WebClient.builder()
                .baseUrl(baseUrl)
                .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .build();
        WebClient.Builder builder =  WebClient.builder().baseUrl(baseUrl);
        if(null != headers && headers.length >0){
            for(Header header:headers){
                builder.defaultHeader(header.key,header.value);
            }
        }else {
            builder.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
        }
        builder.build();
    }

    public <T> Mono<T> get(String uri, Class<T> responseType) {
        return webClient.get()
                .uri(uri)
                .retrieve()
                .bodyToMono(responseType);
    }

    public JSONObject get(String uri) {
        JSONObject rsp = new JSONObject();
        Mono<String> mono = this.get(uri, String.class);
        String monoString = mono.block();
        if(null != monoString){
            rsp = JSON.parseObject(monoString);
        }

        return rsp;

    }


    public <T> Mono<T> post(String uri,Object request, Class<T> responseType,Header... headers) {
        WebClient.RequestHeadersSpec requestHeadersSpec = webClient.post()
                .uri(uri)
                .body(BodyInserters.fromValue(request));
        if(null != headers && headers.length >0){
            for(Header header:headers){
                requestHeadersSpec.header(header.key,header.value);
            }
        }
        return requestHeadersSpec.retrieve().bodyToMono(responseType);

    }

    public JSONObject post(String uri,Object request) {
        JSONObject rsp = new JSONObject();
        Mono<String> mono = this.post(uri,request,String.class);
        String monoString = mono.block();
        if(null != monoString){
            rsp = JSON.parseObject(monoString);
        }

        return rsp;

    }




    public Flux<JSONObject> postForStream(String uri, Object request,Header... headers) {
        WebClient.RequestHeadersSpec requestHeadersSpec = webClient.post()
                .uri(uri)
                .body(BodyInserters.fromValue(request));
        if(null != headers && headers.length >0){
            for(Header header:headers){
                requestHeadersSpec.header(header.key,header.value);
            }
        }
        // 发送GET请求并获取响应流
        Flux<JSONObject> rsp = requestHeadersSpec
                .accept(MediaType.TEXT_EVENT_STREAM)
                .retrieve()
                .bodyToFlux(JSONObject.class);
        return rsp;

    }

    public <T> Mono<T> put(String uri, Object request, Class<T> responseType) {
        return webClient.put()
                .uri(uri)
                .body(BodyInserters.fromValue(request))
                .retrieve()
                .bodyToMono(responseType);
    }


    public JSONObject put(String uri,Object request) {
        JSONObject rsp = new JSONObject();
        Mono<String> mono = this.put(uri,request,String.class);
        String monoString = mono.block();
        if(null != monoString){
            rsp = JSON.parseObject(monoString);
        }

        return rsp;

    }


    public <T> Mono<T> delete(String uri, Class<T> responseType) {
        return webClient.delete()
                .uri(uri)
                .retrieve()
                .bodyToMono(responseType);
    }


    public JSONObject delete(String uri) {
        JSONObject rsp = new JSONObject();
        Mono<String> mono = this.delete(uri, String.class);
        String monoString = mono.block();
        if(null != monoString){
            rsp = JSON.parseObject(monoString);
        }

        return rsp;

    }

}
